
package com.limoilux.cobolux.core.builder;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import com.limoilux.cobolux.core.Cobolux;
import com.limoilux.cobolux.core.ProblemMarker;

public abstract class CobolCompiler
{
	private final List<ProblemMarker> markerList;

	private String errorOutput = null;
	private String binaryExtension = null;
	private String standardOutput = null;
	private String executable = null;
	private int exitValue = 0;
	private long executionTime = 0;

	public CobolCompiler()
	{
		boolean ok = this.setBinaryExtension(Cobolux.BIN_EXTENSION);

		if (!ok)
		{
			throw new RuntimeException("Constructeur invalide");
		}

		this.markerList = new ArrayList<ProblemMarker>();

		this.reset();
	}

	public boolean setBinaryExtension(String binaryExtension)
	{
		this.binaryExtension = binaryExtension;

		return true;
	}

	public String getExectuable()
	{
		return this.executable;
	}

	public String getBinaryExtension()
	{
		return this.binaryExtension;
	}

	public String getErrorOutput()
	{
		return this.errorOutput;
	}

	public String getStandardOutput()
	{
		return this.standardOutput;
	}

	public ListIterator<ProblemMarker> getMarkers()
	{
		return this.markerList.listIterator();
	}

	public int getExitValue()
	{
		return this.exitValue;
	}

	public long getExecutionTime()
	{
		return this.executionTime;
	}

	public void reset()
	{
		this.markerList.clear();
		this.setErrorOutput("");
		this.setExitValue(0);
		this.setExecutionTime(0);
	}

	protected boolean addMarker(ProblemMarker marker)
	{
		boolean ok = CobolCompiler.validMarker(marker);
		if (ok)
		{
			this.markerList.add(marker);
		}

		return ok;
	}

	protected boolean setErrorOutput(String errorOutput)
	{
		this.errorOutput = errorOutput;

		return true;
	}

	protected boolean setStandardOutput(String standardOutput)
	{
		this.standardOutput = standardOutput;

		return true;
	}

	protected boolean setExitValue(int exitValue)
	{
		this.exitValue = exitValue;
		return true;
	}

	protected boolean setExecutionTime(long executionTime)
	{
		this.executionTime = executionTime;
		return true;
	}

	protected boolean setExecutable(String executable)
	{
		this.executable = executable;
		return true;
	}

	public abstract boolean compile(String sourceFile);

	protected abstract ProblemMarker processErrorLine(String errorLine);

	protected abstract String buildCompilationCommand(String source, String binary);

	protected abstract boolean deleteOldBin(String binFile);

	public static boolean validMarker(ProblemMarker marker)
	{
		return marker != null;
	}

	public static boolean validBinaryExtension(String binaryExtension)
	{
		return binaryExtension != null && binaryExtension.length() > 0;
	}
}
